import java.lang.*;
import java.lang.Exception;

class ReceiveEvent extends CommEvent {
	public ReceiveEvent(Channel c) {
		channel = c;
		obj = null;
	}
	
	public void Sync() throws InterruptedException {
		synchronized (Lock.lock) {
			Enqueue();
			if (!Poll()) {
				while ((channel.sendQueue.isEmpty()) ||
					(channel.receiveQueue.getFirst() != this)) {
					Lock.lock.wait();
				}
				Receive();
			}
		}
	}
	
	public boolean Poll() {
		synchronized (Lock.lock) {
			if ((channel.sendQueue.isEmpty()) || 
				((!channel.receiveQueue.isEmpty()) &&
				(channel.receiveQueue.getFirst() != this))) {
				return false;
			}
			
			if (channel.receiveQueue.isEmpty()) {
				channel.receiveQueue.add(this);
			}
			Receive();
			return true;
		}
	}
	
	public void Enqueue() {
		synchronized (Lock.lock) {
			channel.receiveQueue.add(this);
			Lock.lock.notifyAll();
		}
	}
	
	public void Dequeue() {
		synchronized (Lock.lock) {
			channel.receiveQueue.remove(this);
			Lock.lock.notifyAll();
		}
	}
	
	public boolean CommOccurred() {
		synchronized (Lock.lock) {
			if ((!channel.sendQueue.isEmpty()) &&
				(channel.receiveQueue.getFirst() == this)) {
				Receive();
				return true;
			}
			return false;
		}
	}
	
	private void Receive() {
		synchronized (Lock.lock) {
			obj = channel.sendQueue.removeFirst().GetObject();
			channel.receiveQueue.removeFirst();
			Lock.lock.notifyAll();
		}
	}
}
